package com.scalar.chiptrack.adaptor.telefunken;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.FabSortLot;
import com.scalar.chiptrack.adaptor.ShippedLot;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.utils.ParserResult;
import com.scalar.chiptrack.adaptor.utils.Parser;
import com.scalar.chiptrack.adaptor.utils.ParserFactory;
import com.scalar.chiptrack.adaptor.utils.CSVParserImpl;
import com.scalar.chiptrack.adaptor.chartered.CharteredWipStatus;
import com.scalar.chiptrack.adaptor.dao.FabSortAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.ShippedLotDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 * User: munugoti
 * Date: 10 Mar, 2010
 * Time: 3:49:25 PM
 */
public class TeleFunkenDataParser extends JobHandler implements AdaptorConstants
{
       private static Logger m_parserLogger     = null;
       private String m_dataOutputDir           = null;

       private HashMap<String, FabSortLot> m_WipStatusMap   = new HashMap<String, FabSortLot>();
       private HashMap<String, ShippedLot> m_ShipStatusMap  = new HashMap<String, ShippedLot>();
       DBTransaction dbTransaction              = null;

       public TeleFunkenDataParser() throws ScalarException
       {
           try
           {
               m_dataOutputDir = AdaptorUtils.getDataOutputDir(VENDOR_NAME_TELEFUNKEN, WIP_TYPE_FAB);
               AdaptorUtils.makeAllAdaptorDirs(m_dataOutputDir);
               m_parserLogger = AdaptorUtils.getDataParserLogger(m_dataOutputDir, VENDOR_NAME_TELEFUNKEN);
               FabSortAdaptorDAO.setLogger(m_parserLogger);
               ShippedLotDAO.setLogger(m_parserLogger);
               AdaptorUtils.setLogger( m_parserLogger);
           }
           catch ( ScalarException se )
           {
               log( "ERROR!! ERROR!! ERROR!! Exception while loading"+VENDOR_NAME_TELEFUNKEN+" WIP Status output directory details from database, Exception: " + se );
               throw se;
           }
       }

       public static void main( String args[] ) throws Exception
       {
           new TeleFunkenDataParser().execute();
       }

       public void execute() throws Exception
       {
           AdaptorUtils.printHeader(VENDOR_NAME_TELEFUNKEN, CONSTANT_PARSER);

           File doneDestDir = new File( m_dataOutputDir + "/done");

           File wipDataoutDir = new File( m_dataOutputDir );

           File[] fileList = wipDataoutDir.listFiles();

           if ( ( fileList == null ) || ( fileList.length <= 3 ) )
           {
               log( "No file found in directory: " + wipDataoutDir );
               throw new ScalarException( "No file found in directory: " + wipDataoutDir + "----\n\n" );
           }

           ArrayList<File> successFileList    = new ArrayList<File>();
           boolean success              = false;

           //PARSING STARTS FROM HERE
           for ( int i = 0; i < fileList.length; i++ )
           {

               if ( fileList[i].isDirectory() == true )
               {
                   continue;
               }

               if ( ( fileList[i].getName() != null ) && ( fileList[i].getName().trim().startsWith ( TeleFunkenAdaptor.FILE_NAME_WIP ) ) )
               {
                   try
                   {
                        // Parse the file and get the lot list
                        //FileReader reader = new FileReader( fileList[i].getAbsolutePath() );

                        //TeleFunkenHtmlWipParser htmlParser = new TeleFunkenHtmlWipParser();

                        //Here the HTML parsing starts
                        //ArrayList<CharteredWipStatus> m_wipStatusList = htmlParser.parse( reader );

                        /*if ( m_wipStatusList != null && m_wipStatusList.size() > 0 )
                        {
                            getWipStatusInfoList( m_wipStatusList );
                        }*/
						parseDailyWipReport( fileList[i].getAbsolutePath() );

                        //Add files to success list to move to /done directory
                        successFileList.add( fileList[i] );

                        /*try
                        {
                            if ( reader != null)
                            {
                                reader.close();
                                reader = null;
                            }
                        }
                        catch(IOException ignore)
                       {

                       } */
                       success = true;
                   }
                   catch ( Exception e )
                   {
                       success = false;
                       log( "Exception while parsing and storing file: " + fileList[i].getName() + "\nException: " + e );
                       e.printStackTrace();
                       throw e;
                   }

               }// End of WIP
               if ( ( fileList[i].getName() != null ) && ( fileList[i].getName().trim().startsWith( TeleFunkenAdaptor.FILE_NAME_SHIP ) ) )
               {
                   try
                   {
                        parseShipReport( fileList[i].getAbsolutePath() );

                        //Add files to success list to move to /done directory
                        successFileList.add( fileList[i] );
                   }
                   catch ( Exception e )
                   {
                       success = false;
                       log( "Exception while parsing and storing file: " + fileList[i].getName() + "\nException: " + e );
                       e.printStackTrace();
                       throw e;
                   }

               }

           }

           // to save the Fab lot tables
           try
           {
               // Save FAB Lot information
               if ( m_WipStatusMap.isEmpty() == false )
               {
                   log( "Updating Fab Lot Information" );
                   FabSortAdaptorDAO.saveFabLot( dbTransaction, m_WipStatusMap.values().iterator(), WIP_TYPE_FAB, VENDOR_NAME_TELEFUNKEN );
               }
               success = true;
           }
           catch ( Exception e )
           {
               success = false;
               log( "ERROR!! ERROR!! ERROR!! Could not update Fab Data information into database: " + e );
               e.printStackTrace();
               throw e;
           }

           try
           {
               // Save shipping info
               if ( m_ShipStatusMap.isEmpty() == false )
               {
                   log( "Updating shipment Information" );
                   ShippedLotDAO.saveShippedLot( dbTransaction, m_ShipStatusMap.values().iterator() );
               }
           }
           catch ( Exception e )
           {
               success = false;
               log( "ERROR!! ERROR!! ERROR!! Could not update Telefunken Shipping information into database: " + e );
               e.printStackTrace();
               throw e;
           }

           // To Close the Drop Out Lots
           AdaptorDAO.closeDropOutLots( VENDOR_NAME_TELEFUNKEN );

           // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
           AdaptorDAO.sendAllNotifications( VENDOR_NAME_TELEFUNKEN, true, true, true );


           int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( TeleFunkenAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

            // Update Adaptor_Run_Info table
            try
            {
                if ( success == true )
                {
                    AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, TeleFunkenAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                    System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
                }
            }
            catch ( ScalarException se )
            {
                success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, TeleFunkenAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
                throw se;
            }

           // Step 7
           // Move the successful files to 'done' directory
           if ( success )
           {
               AdaptorUtils.moveFilesToDone(successFileList, doneDestDir );
           }
       }//end of execute method

       /**
       *
       * @param wipdataList
       */
       public void getWipStatusInfoList( ArrayList wipdataList ) throws ScalarException
       {
           if ( wipdataList == null || wipdataList.size() == 0 )
           {
               return;
           }

           CharteredWipStatus wipStatusReport   = null;
           String partNumber                    = null;
           String lotNumber                     = null;
           FabSortLot fabSortLot                = null;
           try
           {
               Iterator iterator = wipdataList.iterator();
               while ( iterator.hasNext() )
               {
                   wipStatusReport = ( CharteredWipStatus ) iterator.next();

                   if ( wipStatusReport != null )
                   {
                       partNumber = wipStatusReport.getCustomerProduct();
                       lotNumber  = wipStatusReport.getCustomerLot() ;
                       
                       if ( lotNumber != null && partNumber != null )
                       {
                           fabSortLot = ( FabSortLot ) m_WipStatusMap.get( partNumber + lotNumber );
                           if ( fabSortLot == null )
                           {
                               fabSortLot = new FabSortLot(VENDOR_NAME_TELEFUNKEN, WIP_TYPE_FAB);
                               m_WipStatusMap.put( partNumber + lotNumber , fabSortLot );
                           }
                           int quantity = 0;
                           if ( fabSortLot.getQtyIn() != null )
                           {
                               try
                               {
                                   quantity = Integer.parseInt ( fabSortLot.getQtyIn() );
                               }
                               catch ( NumberFormatException ignore )
                               {
                               }
                               try
                               {
                                   quantity += Integer.parseInt ( wipStatusReport.getWaferQty() );
                               }
                               catch ( NumberFormatException ignore )
                               {
                               }
                           }
                           else
                           {
                               try
                               {
                                   quantity = Integer.parseInt ( wipStatusReport.getWaferQty() );
                               }
                               catch ( NumberFormatException ignore )
                               {
                               }
                           }

                           String dateIn           = null;
                           String expectedDateOut  = null;

                           if ( wipStatusReport.getDateIn() != null && wipStatusReport.getDateIn().trim().length() > 0 )
                           {
                                dateIn = StringUtils.formatDate ( wipStatusReport.getDateIn(), "dd MMM yyyy", "MM/dd/yyyy" );
                           }

                           if( wipStatusReport.getExpectedDateOut() != null && wipStatusReport.getExpectedDateOut().trim().length() > 0 )
                           {
                                expectedDateOut = StringUtils.formatDate ( wipStatusReport.getExpectedDateOut(), "dd MMM yyyy", "MM/dd/yyyy" );
                           }

                           if ( quantity > 0 )
                           {
                               fabSortLot.setProcess ( wipStatusReport.getProcessName());
                               fabSortLot.setShip_fcst_date( expectedDateOut );
                               fabSortLot.setFabLotNumber(lotNumber);
                               fabSortLot.setLotId( lotNumber );
                               fabSortLot.setCustProduct( partNumber );
                               fabSortLot.setDateIn( dateIn );
                               fabSortLot.setQtyIn( quantity +"");
                               fabSortLot.setStage( wipStatusReport.getCurrentStage() );
                               fabSortLot.setForcastedDateOut( expectedDateOut );
                               fabSortLot.setLotCategory ( LOT_CATEGORY_TYPE_PROD );
                               fabSortLot.setLotStatus ( LOT_STATUS_RUNNING );
                           }
                       }
                   }
               }
           }
           catch(Exception e )
           {
             log( "ERROR!!! ERROR!!! While Parsing the telefunken Fab Data" + e);
             e.printStackTrace();
             throw new ScalarException("ERROR!!! ERROR!!! While Parsing the telefunken Fab Data" + e );
           }
        }
        private void parseDailyWipReport( String fileName ) throws Exception
   	    {
            if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

            ParserResult result            = null;
            FabSortLot fabSortLot   = null;
            String lotNumber        = null;
            String partNumber       = null;

            try
            {
                File fabWipFile = new File( fileName );
                if ( fabWipFile.exists() == false )
                {
                    throw new ScalarException( fileName + " doesnt exist" );
                }

                log( "\nFound " + fileName );
                log( "\nParsing the file for Fab Wip Report..." );
                System.out.println( "\nFound " + fileName );
                System.out.println( "\nParsing the file for Fab Wip Report..." );

                Parser parser = ParserFactory.getCSVParser( fabWipFile, ';' );

                ((CSVParserImpl)parser).setHeaderRowIdx(-1);
                ((CSVParserImpl)parser).setDataStartRowIdx(0);

                result = parser.parse();
    
                while ( result.next() )
                {
                    partNumber = result.getString(1);
                    lotNumber  = result.getString(2);

                    if ( partNumber != null && partNumber.trim().length() > 0 && lotNumber != null && lotNumber.trim().length() > 0 )
                    {
                         fabSortLot = ( FabSortLot ) m_WipStatusMap.get( partNumber + lotNumber );
                         if ( fabSortLot == null )
                         {
                             fabSortLot = new FabSortLot(VENDOR_NAME_TELEFUNKEN, WIP_TYPE_FAB);
                             m_WipStatusMap.put( partNumber + lotNumber , fabSortLot );
                         }

                         int quantity = 0;

                         if( fabSortLot.getQtyIn() != null )
                         {
                             try
                             {
                                 quantity = Integer.parseInt( fabSortLot.getQtyIn() );
                             }
                             catch ( NumberFormatException ignore )
                             {
                             }
                             quantity += result.getInt(3);
                         }
                         else
                         {
                             quantity = result.getInt(3);
                         }

                         String dateIn           = null;
                         String expectedDateOut  = null;

                         if ( result.getString(4) != null && result.getString(4).trim().length() > 8 )
                         {
                              dateIn = StringUtils.formatDate ( result.getString(4), "dd-MMM-yyyy", "MM/dd/yyyy" );
                         }

                         if( result.getString(7) != null && result.getString(7).trim().length() > 8 )
                         {
                              expectedDateOut = StringUtils.formatDate ( result.getString(7), "dd-MMM-yyyy", "MM/dd/yyyy" );
                         }

                         if ( quantity > 0 )
                         {
                             fabSortLot.setProcess (result.getString(8) );
                             fabSortLot.setShip_fcst_date( expectedDateOut );
                             fabSortLot.setFabLotNumber(lotNumber);
                             fabSortLot.setLotId( lotNumber );
                             fabSortLot.setCustProduct( partNumber );
                             fabSortLot.setDateIn( dateIn );
                             fabSortLot.setQtyIn( quantity +"");
                             fabSortLot.setStage( result.getString(6) );
                             fabSortLot.setForcastedDateOut( expectedDateOut );
                             fabSortLot.setLotCategory ( LOT_CATEGORY_TYPE_PROD );
                             fabSortLot.setLotStatus ( LOT_STATUS_RUNNING );
                         }
                    }
                }
            }
            catch ( Exception ex )
            {   System.out.println("ERROR!!!ERROR!!! While Parsing the Telefunken Daily wip Sheet");
                ex.printStackTrace();
                throw ex;
            }
       } // end Of parse Ship ment

       private void parseShipReport( String fileName ) throws Exception
   	   {
            if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

            ParserResult result     = null;
            ShippedLot shippedLot   = null;
            String lotNumber        = null;
            String partNumber       = null;

            try
            {
                File fabWipFile = new File( fileName );
                if ( fabWipFile.exists() == false )
                {
                    throw new ScalarException( fileName + " doesnt exist" );
                }

                log( "\nFound " + fileName );
                log( "\nParsing the file for Ship Report..." );
                System.out.println( "\nFound " + fileName );
                System.out.println( "\nParsing the file for Ship Report..." );

                Parser parser = ParserFactory.getCSVParser( fabWipFile, '\t' );

                ((CSVParserImpl)parser).setHeaderRowIdx(0);
                ((CSVParserImpl)parser).setDataStartRowIdx(1);

                result = parser.parse();

                while ( result.next() )
                {
                    partNumber = result.getString("CUSTOMER_PARTNUMBER");
                    lotNumber  = result.getString("ISTOCK_ID");
                    String shipDate = null;
                    if ( result.getString("DELIVERY_DATE") != null )
                    {
                        shipDate   = StringUtils.formatDate(result.getString("DELIVERY_DATE"), "dd.MM.yyyy HH:mm:ss", "MM/dd/yyyy HH:mm:ss" );
                    }

                    if ( partNumber != null && partNumber.trim().length() > 0 && lotNumber != null && lotNumber.trim().length() > 0 )
                    {
                         shippedLot = ( ShippedLot ) m_ShipStatusMap.get( partNumber + lotNumber + shipDate );
                           if ( shippedLot == null )
                           {
                               shippedLot = new ShippedLot(VENDOR_NAME_TELEFUNKEN, LOCATION_TYPE_FAB);
                               m_ShipStatusMap.put( partNumber + lotNumber + shipDate  , shippedLot );
                           }
                           int quantity = 0;
                           String Qty = null;
                           if ( shippedLot.getShipQty() != null )
                           {
                               try
                               {
                                   quantity = Integer.parseInt ( shippedLot.getShipQty() );
                               }
                               catch ( NumberFormatException ignore )
                               {
                               }
                               try
                               {
                                   Qty = result.getString("DELIVERED_QUANTITY").replaceAll("[a-zA-Z]", "");
                                   quantity += Integer.parseInt ( Qty != null ? Qty.trim() : "0" );
                               }
                               catch ( NumberFormatException ignore )
                               {
                               }
                           }
                           else
                           {
                               Qty = result.getString("DELIVERED_QUANTITY").replaceAll("[a-zA-Z]", "");
                               try
                               {
                                   quantity = Integer.parseInt ( Qty != null ? Qty.trim() : "0" );
                               }
                               catch ( NumberFormatException ignore )
                               {
                               }
                           }
                           if ( quantity > 0 )
                           {
                               shippedLot.setPartNumber( partNumber);
                               shippedLot.setLotNumber( lotNumber );
                               shippedLot.setFabLotNumber( lotNumber );
                               shippedLot.setShipDate (  shipDate );
                               shippedLot.setShipQty ( quantity +"" );
                               shippedLot.setCustomerPO ( result.getString("EXTERNAL_REFERENCE") );
                           }
                    }
                }
            }
            catch ( Exception ex )
            {   System.out.println("ERROR!!!ERROR!!! While Parsing the Telefunken Ship Sheet");
                ex.printStackTrace();
                throw ex;
            }
       }
       private static void log( String message )
       {

           if ( message == null ) return;

           if ( m_parserLogger != null )
           {
               synchronized ( m_parserLogger )
               {
                   m_parserLogger.logDebug ( message + LINE_SEPARATOR );
               }
           }
           else
           {
               System.out.println ( message );
           }
       }
}

